package com.lagou.cl;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONObject;
import com.lagou.cl.config.Constant;
import com.lagou.cl.config.DriudPoolConf;
import com.lagou.cl.config.ZooKeeperProperties;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 程  林
 * @date 2020-06-04 01:09
 * @description //
 * @since V1.0.0
 */
@SpringBootApplication(scanBasePackages = {"com.lagou"})
public class WebZkConfigApplication implements CommandLineRunner {

	private Logger logger = LoggerFactory.getLogger(WebZkConfigApplication.class);

	public static DruidDataSource dataSource = null;

	private final CuratorFramework curatorFramework;

	private final ZooKeeperProperties zkProperties;

	public WebZkConfigApplication(CuratorFramework curatorFramework, ZooKeeperProperties zkProperties) {
		this.curatorFramework = curatorFramework;
		this.zkProperties = zkProperties;
	}

	public static void main(String[] args) {
		SpringApplication.run(WebZkConfigApplication.class);
	}

	@Override
	public void run(String... args) throws Exception {

		String zkConfigPath = "/" + Constant.ZKCONFIG;

		//连接zk服务端
		curatorFramework.start();
		curatorFramework.blockUntilConnected();
		logger.info("当前应用 已连接上zookeeper服务端：{}", zkProperties.getZkHost() + ":" + zkProperties.getPort());

		setListeners(zkConfigPath);
	}

	private void setListeners(String path) throws Exception {

		PathChildrenCache childrenCache = new PathChildrenCache(curatorFramework, path, true);
		PathChildrenCacheListener childrenCacheListener = (client, event) -> {
			ChildData data = event.getData();

			switch (event.getType()) {
				//添加子节点
				case CHILD_ADDED:
					String nodeData = new String(data.getData());
					logger.info("~~~~~~ 新增子节点事件 获取连接");
					createPool(data, nodeData);
					break;
				//移除子节点
				case CHILD_REMOVED:
					logger.info("~~~~~~ 移除子节点事件 关闭连接");
					if (data.getPath().contains("database")) {
						dataSource = null;
					}
					break;
				//子节点的数据变化
				case CHILD_UPDATED:
					String nodeDataa = new String(data.getData());
					logger.info("~~~~~~ 子节点数据变化事件 重新获取连接");
					createPool(data, nodeDataa);
					break;
				default:
					break;
			}
		};
		childrenCache.getListenable().addListener(childrenCacheListener);
		childrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
	}

	private void createPool(ChildData data, String nodeData) {
		if (data.getPath().contains("database")) {
			DriudPoolConf driudPoolConf = JSONObject.parseObject(nodeData, DriudPoolConf.class);
			logger.info("创建数据源：{}", nodeData);
			dataSource = new DruidDataSource();
			dataSource.setUrl(driudPoolConf.getUrl());
			dataSource.setUsername(driudPoolConf.getUsername());
			dataSource.setPassword(driudPoolConf.getPassword());
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		}
	}

}
